package org.bim.view.drag.design.model;

import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;
import org.bim.view.drag.design.exception.BizCommonException;
import org.bim.view.drag.design.util.ErrorCodeUtil;

/**
 * HTTP请求通用返回结果
 *
 * @author bim-view
 * @since 2021-07-05
 */
@Setter
@Getter
@Accessors(chain = true)
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class HttpResult<T> {

    /**
     * 状态码，0正常，1异常
     */
    @ApiModelProperty("状态码，0正常，其他异常")
    private int code;

    /**
     * 状态布尔值，true正常，false异常
     */
    @ApiModelProperty("状态布尔值，true正常，false异常")
    private boolean status;

    /**
     * 附加的信息
     */
    @ApiModelProperty("错误原因")
    private String message;

    /**
     * 具体数据
     */
    @ApiModelProperty("返回数据")
    private T data;
    /**
     * 接口返回信息
     */
    @ApiModelProperty("接口返回时间")
    private long time;
    /**
     * 打印具体详细的错误堆栈信息
     */
    @ApiModelProperty("错误堆栈信息")
    private String error;

    public static HttpResult success() {
        return new HttpResult<>(0, true, "success", null);
    }

    public static <T> HttpResult<T> success(T data) {
        return new HttpResult<>(0, true, "success", data);
    }

    public static <T> HttpResult<T> success(T data, String message) {
        return new HttpResult<>(0, true, message, data);
    }

    public static <T> HttpResult<T> fail(String message) {
        return new HttpResult<>(1, false, message, null);
    }

    public HttpResult error(String error) {
        return this.setError(error);
    }

    public HttpResult error(Exception error) {
        return this.setError(error.getMessage());
    }

    public static <T> HttpResult error(int code) {
        String errorMsg = ErrorCodeUtil.getErrorMessage(code);
        if (errorMsg == null) {
            errorMsg = ErrorCodeUtil.getErrorMessage(-1);
        }
        return new HttpResult<>(code, false, errorMsg, null).setError(errorMsg);
    }

    /**
     * 设置错误堆栈
     *
     * @param code  错误码
     * @param error 错误堆栈
     * @return HttpResult
     */
    public static HttpResult error(int code, String error) {
        String errorMsg = ErrorCodeUtil.getErrorMessage(code);
        if (errorMsg == null) {
            errorMsg = ErrorCodeUtil.getErrorMessage(-1);
        }
        return new HttpResult<>(code, false, errorMsg, null).setError(error);
    }

    /**
     * 设置错误堆栈
     *
     * @param code   错误码
     * @param error  错误堆栈
     * @param params 错误消息占位符参数
     * @return HttpResult
     */
    public static HttpResult error(int code, String error, String... params) {
        String errorMsg = ErrorCodeUtil.getErrorMessage(code, params);
        if (errorMsg == null) {
            errorMsg = ErrorCodeUtil.getErrorMessage(-1);
        }
        return new HttpResult<>(code, false, errorMsg, null).setError(error);
    }

    /**
     * 设置错误堆栈
     *
     * @param code      错误码
     * @param exception 错误堆栈
     * @return HttpResult
     */
    public static HttpResult error(int code, Exception exception) {
        String errorMsg = ErrorCodeUtil.getErrorMessage(code);
        if (errorMsg == null) {
            errorMsg = ErrorCodeUtil.getErrorMessage(-1);
        }
        return new HttpResult<>(code, false, errorMsg, null).setError(exception.getMessage());
    }

    public static HttpResult error(BizCommonException exception) {
        return new HttpResult<>(exception.getCode(), false, exception.getMsg(), null).setError(exception.getMessage());
    }

    /**
     * 设置错误堆栈
     *
     * @param code      错误码
     * @param exception 错误堆栈
     * @param params    错误消息占位符参数
     * @return HttpResult
     */
    public static HttpResult error(int code, Exception exception, String... params) {
        String errorMsg = ErrorCodeUtil.getErrorMessage(code, params);
        if (errorMsg == null) {
            errorMsg = ErrorCodeUtil.getErrorMessage(-1);
        }
        return new HttpResult<>(code, false, errorMsg, null).setError(exception.getMessage());
    }

    public static <T> HttpResult<T> fail(int code, String message) {
        return new HttpResult<>(code == 0 ? 1 : code, false, message, null);
    }

    public static <T> HttpResult fail(int code, String message, String error) {
        return new HttpResult<>(code == 0 ? 1 : code, false, message, null).setError(error);
    }

    public static <T> HttpResult fail(int code, String message, Exception error) {
        return new HttpResult<>(code == 0 ? 1 : code, false, message, null).setError(error.getMessage());
    }

    private HttpResult(int code, boolean status, String message, T data) {
        this.code = code;
        this.status = status;
        this.message = message;
        this.data = data;
        this.time = System.currentTimeMillis();
    }


}
